package team.seekers.hula.common.utils;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import team.seekers.hula.common.entity.enums.LoginTypeEnum;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 跟微信相关的一些工具
 * @author hbc
 */

public class WxUtil {

    private final static String appId = "wxf53f1fd727101f0f";
    private final static String secretId = "844fba0b08b0e1b31a247869b29a55dd";

    /**
     * 根据code前往微信服务器获取唯一openId
     * @param code
     * @return openId
     */
    public static String getUnionId(String code, LoginTypeEnum loginType) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 参数
        StringBuilder params = new StringBuilder();
        try {
            // 字符数据最好encoding以下;这样一来，某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
            params.append("appid=").append(URLEncoder.encode(loginType.getAppid(), "utf-8"));
            params.append("&");
            params.append("secret="+loginType.getSecretId());
            params.append("&");
            if (loginType.equals(LoginTypeEnum.MINI_APP))
                params.append("js_code=").append(URLEncoder.encode(code, "utf-8"));
            else
                params.append("code=").append(URLEncoder.encode(code, "utf-8"));
            params.append("&");
            params.append("grant_type=authorization_code");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }

        // 创建Post请求
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        if(loginType.equals(LoginTypeEnum.MINI_APP))
            url = "https://api.weixin.qq.com/sns/jscode2session";
        HttpPost httpPost = new HttpPost(url + "?" + params);
        httpPost.setHeader("Content-Type", "application/json;charset=utf8");

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);

            System.out.println(response);

            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println(responseEntity);
            // 解析openId,实现登录
            String result = EntityUtils.toString(responseEntity);

            System.out.println(result);
            Map mapType = JSON.parseObject(result,Map.class);

            System.out.println(mapType);
            return (String)mapType.get("unionid");
        } catch (ParseException | IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据code前往微信服务器获取唯一openId和unionId，并将openId存储
     * @param code
     * @return openId
     */
    public static HashMap<String, String> getUnionIdAndOpenId(String code, LoginTypeEnum loginType) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 参数
        StringBuilder params = new StringBuilder();
        try {
            // 字符数据最好encoding以下;这样一来，某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
            params.append("appid=").append(URLEncoder.encode(loginType.getAppid(), "utf-8"));
            params.append("&");
            params.append("secret="+loginType.getSecretId());
            params.append("&");
            if (loginType.equals(LoginTypeEnum.MINI_APP))
                params.append("js_code=").append(URLEncoder.encode(code, "utf-8"));
            else
                params.append("code=").append(URLEncoder.encode(code, "utf-8"));
            params.append("&");
            params.append("grant_type=authorization_code");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }

        // 创建Post请求
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        if(loginType.equals(LoginTypeEnum.MINI_APP))
            url = "https://api.weixin.qq.com/sns/jscode2session";
        HttpPost httpPost = new HttpPost(url + "?" + params);
        httpPost.setHeader("Content-Type", "application/json;charset=utf8");

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);

            System.out.println(response);

            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println(responseEntity);
            // 解析openId,实现登录
            String result = EntityUtils.toString(responseEntity);

            System.out.println(result);
            Map mapType = JSON.parseObject(result,Map.class);

            System.out.println(mapType);

            HashMap<String, String> ids = new HashMap<>();
            ids.put("openId",(String)mapType.get("openid"));
            ids.put("unionId",(String)mapType.get("unionid"));
            return ids;
        } catch (ParseException | IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
